<template>
  <div class="message" :class="{ 'user-message': isUser }" ref="messageRef">
    <div class="message-avatar">
      <div :class="isUser ? 'user-avatar' : 'bot-avatar'">
        {{ isUser ? '用户' : 'AI' }}
      </div>
    </div>
    <div class="message-content">
      <div class="message-text" :class="{ 'collapsed': isCollapsed && needsCollapse }">
        <div v-if="!isUser" v-html="formattedContent"></div>
        <span v-else>{{ content }}</span>
      </div>
      
      <!-- 折叠按钮 -->
      <button 
        v-if="!isUser && needsCollapse" 
        class="collapse-btn" 
        @click="toggleCollapse"
      >
        {{ isCollapsed ? '展开 ▼' : '收起 ▲' }}
      </button>
      
      <!-- AI消息操作栏 -->
      <div v-if="!isUser" class="message-footer">
        <div class="message-footer-meta">
          <div class="message-time">
            <span v-if="timestamp">{{ formatTime(timestamp) }}</span>
            <span v-else class="unknown-time">旧记录(无时间戳)</span>
          </div>
          
          <div class="message-actions">
            <!-- 反馈按钮（问题是否解决） -->
            <div class="feedback-buttons">
              <button 
                class="feedback-btn" 
                :class="{ 'active': feedbackStatus === true }" 
                @click="handleFeedback(true)" 
                title="问题已解决"
                :disabled="feedbackStatus !== null">
                <span class="feedback-icon">👍</span>
                <span class="action-text">已解决</span>
              </button>
              <button 
                class="feedback-btn" 
                :class="{ 'active': feedbackStatus === false }" 
                @click="handleFeedback(false)" 
                title="问题未解决"
                :disabled="feedbackStatus !== null">
                <span class="feedback-icon">👎</span>
                <span class="action-text">未解决</span>
              </button>
            </div>
            
            <button class="action-btn" @click="handleTextToSpeech" :class="{ 'active': isSpeaking }" title="语音播报">
              <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
                <path d="M11 5L6 9H2v6h4l5 4V5z"/>
                <path d="M19.07 4.93a10 10 0 0 1 0 14.14M15.54 8.46a5 5 0 0 1 0 7.07"/>
              </svg>
              <span class="action-text">语音播报</span>
            </button>
            
            <button class="action-btn" @click="handleCopyAll" :class="{ 'copied': isCopied }" title="复制全部">
              <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
                <rect x="9" y="9" width="13" height="13" rx="2" ry="2"/>
                <path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/>
              </svg>
              <span class="action-text">复制</span>
            </button>
            
            <button class="action-btn" @click="handleShareAsImage" title="分享为图片">
              <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
                <circle cx="18" cy="5" r="3"/>
                <circle cx="6" cy="12" r="3"/>
                <circle cx="18" cy="19" r="3"/>
                <line x1="8.59" y1="13.51" x2="15.42" y2="17.49"/>
                <line x1="15.41" y1="6.51" x2="8.59" y2="10.49"/>
              </svg>
              <span class="action-text">分享</span>
            </button>
            
            <!-- 重新生成按钮（仅最后一条AI消息） -->
            <button 
              v-if="isLastAiMessage && versions && versions.length > 0" 
              class="action-btn reload-btn" 
              @click="handleRegenerate" 
              :disabled="isRegenerating"
              title="重新生成">
              <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
                <path d="M1 4v6h6M23 20v-6h-6"/>
                <path d="M20.49 9A9 9 0 0 0 5.64 5.64L1 10m22 4l-4.64 4.36A9 9 0 0 1 3.51 15"/>
              </svg>
              <span class="action-text" v-if="!isRegenerating">重新生成</span>
              <span class="action-text" v-else>生成中...</span>
            </button>
          </div>
        </div>
        
        <!-- 版本切换UI（当有多个版本时显示） -->
        <div v-if="!isUser && versions && versions.length > 1" class="version-nav">
          <button 
            class="version-nav-btn" 
            @click="switchToPreviousVersion"
            :disabled="props.currentVersionIndex === 0"
            title="上一个版本">
            ←
          </button>
          <span class="version-count">{{ props.currentVersionIndex + 1 }}/{{ versions.length }}</span>
          <button 
            class="version-nav-btn" 
            @click="switchToNextVersion"
            :disabled="props.currentVersionIndex === versions.length - 1"
            title="下一个版本">
            →
          </button>
        </div>
      </div>
      
      <div class="message-time user-time" v-else>
        <span v-if="timestamp">{{ formatTime(timestamp) }}</span>
        <span v-else class="unknown-time">旧记录(无时间戳)</span>
      </div>
    </div>
  </div>
</template>

<script setup>
import { defineProps, computed, ref, nextTick, onMounted, onUnmounted, watch } from 'vue';
import { marked } from 'marked';
import hljs from 'highlight.js';
import katex from 'katex';
import html2canvas from 'html2canvas';

const props = defineProps({
  messageId: {
    type: Number,
    required: true
  },
  isUser: {
    type: Boolean,
    required: true
  },
  content: {
    type: String,
    required: true
  },
  timestamp: {
    type: [Date, null],
    required: true
  },
  versions: {
    type: Array,
    default: null
  },
  currentVersionIndex: {
    type: Number,
    default: 0
  },
  isLastAiMessage: {
    type: Boolean,
    default: false
  }
});

const emit = defineEmits(['regenerate', 'switch-version']);

// 生成消息唯一ID（基于内容和时间戳）
const messageId = computed(() => {
  const contentHash = btoa(unescape(encodeURIComponent(props.content))).substring(0, 16);
  const timeHash = props.timestamp ? props.timestamp.getTime() : 'no_timestamp';
  return `msg_${contentHash}_${timeHash}`;
});

// 状态
const isCollapsed = ref(false);
const contentHeight = ref(0);
const messageRef = ref(null);
const isSpeaking = ref(false);
const isCopied = ref(false);
const currentUtterance = ref(null);
const isRegenerating = ref(false);
const feedbackStatus = ref(null); // null=未反馈, true=已解决, false=未解决

// 从localStorage读取折叠状态
const loadCollapseState = () => {
  const saved = localStorage.getItem(`collapse_${messageId.value}`);
  if (saved !== null) {
    isCollapsed.value = JSON.parse(saved);
  }
};

// 从localStorage读取反馈状态
const loadFeedbackState = () => {
  const saved = localStorage.getItem(`feedback_${messageId.value}`);
  if (saved !== null) {
    feedbackStatus.value = JSON.parse(saved);
  }
};

// 保存折叠状态到localStorage
const saveCollapseState = () => {
  localStorage.setItem(`collapse_${messageId.value}`, JSON.stringify(isCollapsed.value));
};

const formatTime = (date) => {
  // 确保显示北京时间 (UTC+8)
  return new Date(date).toLocaleTimeString('zh-CN', {
    timeZone: 'Asia/Shanghai',
    hour12: false, // 使用24小时制
    hour: '2-digit',
    minute: '2-digit',
    second: '2-digit'
  });
};

// 配置marked
marked.setOptions({
  highlight: function(code, lang) {
    if (lang && hljs.getLanguage(lang)) {
      try {
        return hljs.highlight(code, { language: lang }).value;
      } catch (err) {
        console.error('Highlight error:', err);
      }
    }
    return hljs.highlightAuto(code).value;
  },
  breaks: true,  // 支持换行
  gfm: true,     // 启用GitHub风格的Markdown
});

// 在HTML中渲染LaTeX公式（避免处理代码块）
const renderLatexInHTML = (html) => {
  // 临时保存代码块，避免被LaTeX处理
  const codeBlocks = [];
  const codeBlockPlaceholder = '___CODE_BLOCK_PLACEHOLDER_';
  
  // 提取并保护所有代码块（<pre>和<code>标签）
  html = html.replace(/<pre[^>]*>[\s\S]*?<\/pre>/g, (match) => {
    codeBlocks.push(match);
    return `${codeBlockPlaceholder}${codeBlocks.length - 1}___`;
  });
  
  html = html.replace(/<code[^>]*>.*?<\/code>/g, (match) => {
    codeBlocks.push(match);
    return `${codeBlockPlaceholder}${codeBlocks.length - 1}___`;
  });
  
  // 处理块级公式 $$...$$ 
  html = html.replace(/\$\$([^\$]+?)\$\$/g, (match, formula) => {
    try {
      return `<div class="latex-block">${katex.renderToString(formula.trim(), { 
        throwOnError: false,
        displayMode: true 
      })}</div>`;
    } catch (e) {
      console.error('LaTeX block error:', e);
      return match;
    }
  });
  
  // 处理方括号块级公式 \[ ... \]
  html = html.replace(/\\\[([\s\S]*?)\\\]/g, (match, formula) => {
    try {
      return `<div class="latex-block">${katex.renderToString(formula.trim(), { 
        throwOnError: false,
        displayMode: true 
      })}</div>`;
    } catch (e) {
      console.error('LaTeX block error:', e);
      return match;
    }
  });
  
  // 处理简化的方括号块级公式 [ ... ]（智能识别）
  html = html.replace(/\[\s*([^\[\]]+?)\s*\]/g, (match, formula) => {
    if (/[\\^_{}]|frac|sqrt|sum|int|alpha|beta|gamma|delta/.test(formula)) {
      try {
        return `<div class="latex-block">${katex.renderToString(formula.trim(), { 
          throwOnError: false,
          displayMode: true 
        })}</div>`;
      } catch (e) {
        console.error('LaTeX block error:', e);
        return match;
      }
    }
    return match;
  });
  
  // 处理行内公式 \( ... \)
  html = html.replace(/\\\((.*?)\\\)/g, (match, formula) => {
    try {
      return katex.renderToString(formula.trim(), { throwOnError: false });
    } catch (e) {
      console.error('LaTeX inline error:', e);
      return match;
    }
  });
  
  // 处理行内公式 $...$（但要避免 ${} 这种JS模板字符串语法）
  html = html.replace(/\$(?!\{)([^\$\n]+?)\$/g, (match, formula) => {
    try {
      return katex.renderToString(formula.trim(), { throwOnError: false });
    } catch (e) {
      console.error('LaTeX inline error:', e);
      return match;
    }
  });
  
  // 恢复代码块
  codeBlocks.forEach((block, index) => {
    html = html.replace(`${codeBlockPlaceholder}${index}___`, block);
  });
  
  return html;
};

// 使用computed处理Markdown渲染
const formattedContent = computed(() => {
  if (!props.content) return '';
  
  // 先处理Markdown（保护代码块）
  let content = marked(props.content);
  
  // 再处理LaTeX公式（此时代码块已经被<pre><code>包裹，不会被误处理）
  content = renderLatexInHTML(content);
  
  return content;
});

// 复制代码
const copyCode = (event) => {
  const button = event.target.closest('.copy-btn');
  if (!button) return;
  
  const codeBlock = button.parentElement.querySelector('code');
  if (!codeBlock) return;
  
  const code = codeBlock.textContent;
  
  navigator.clipboard.writeText(code).then(() => {
    button.textContent = '✓ 已复制';
    button.classList.add('copied');
    
    // 复制成功的样式
    button.style.background = '#dcfce7';
    button.style.borderColor = '#86efac';
    button.style.color = '#16a34a';
    
    setTimeout(() => {
      button.textContent = '复制';
      button.classList.remove('copied');
      
      // 恢复默认样式
      button.style.background = 'rgba(255, 255, 255, 0.9)';
      button.style.borderColor = '#d1d5db';
      button.style.color = '#6b7280';
    }, 2000);
  }).catch(err => {
    console.error('复制失败:', err);
    button.textContent = '复制失败';
    
    // 失败的样式
    button.style.background = '#fee2e2';
    button.style.borderColor = '#fca5a5';
    button.style.color = '#dc2626';
  });
};

// 添加复制按钮到代码块
const addCopyButtons = () => {
  nextTick(() => {
    if (!messageRef.value) return;
    
    const codeBlocks = messageRef.value.querySelectorAll('pre');
    console.log(`🔍 找到 ${codeBlocks.length} 个代码块`);
    
    codeBlocks.forEach((pre, index) => {
      // 避免重复添加
      if (pre.querySelector('.copy-btn')) {
        console.log(`⚠️ 代码块 ${index} 已有复制按钮，跳过`);
        return;
      }
      
      console.log(`✅ 为代码块 ${index} 添加复制按钮`);
      
      const button = document.createElement('button');
      button.className = 'copy-btn';
      button.textContent = '复制';
      button.onclick = copyCode;
      
      // 直接设置按钮样式（确保可见）
      Object.assign(button.style, {
        position: 'absolute',
        top: '0.5rem',
        right: '0.5rem',
        padding: '0.25rem 0.75rem',
        background: 'rgba(255, 255, 255, 0.9)',
        border: '1px solid #d1d5db',
        borderRadius: '0.375rem',
        fontSize: '0.75rem',
        cursor: 'pointer',
        color: '#6b7280',
        fontWeight: '500',
        zIndex: '10',
        transition: 'all 0.2s'
      });
      
      // 悬停效果
      button.onmouseenter = () => {
        button.style.background = '#f3f4f6';
        button.style.borderColor = '#9ca3af';
        button.style.color = '#374151';
      };
      
      button.onmouseleave = () => {
        if (!button.classList.contains('copied')) {
          button.style.background = 'rgba(255, 255, 255, 0.9)';
          button.style.borderColor = '#d1d5db';
          button.style.color = '#6b7280';
        }
      };
      
      pre.style.position = 'relative';
      pre.appendChild(button);
    });
  });
};

// 切换折叠状态
const toggleCollapse = () => {
  isCollapsed.value = !isCollapsed.value;
  saveCollapseState();
};

// 检查内容高度并决定是否显示折叠按钮
const checkContentHeight = () => {
  nextTick(() => {
    if (!messageRef.value) return;
    const textElement = messageRef.value.querySelector('.message-text');
    if (textElement) {
      contentHeight.value = textElement.scrollHeight;
    }
  });
};

// 内容是否需要折叠（高度超过500px）
const needsCollapse = computed(() => contentHeight.value > 500);

// 监听内容变化
onMounted(() => {
  loadCollapseState();
  loadFeedbackState(); // 加载反馈状态
  addCopyButtons();
  checkContentHeight();
});

// 当内容更新时
const contentUpdated = () => {
  addCopyButtons();
  checkContentHeight();
};

// 使用watch监听formattedContent变化
watch(formattedContent, () => {
  contentUpdated();
});

// 语音播报功能
const handleTextToSpeech = () => {
  if (isSpeaking.value) {
    // 停止播报
    if (currentUtterance.value) {
      window.speechSynthesis.cancel();
      currentUtterance.value = null;
      isSpeaking.value = false;
    }
  } else {
    // 开始播报
    let text = props.content;
    
    // 移除代码块
    text = text.replace(/```[\s\S]*?```/g, '');
    
    // 移除Markdown标题符号
    text = text.replace(/^#{1,6}\s*/gm, '');
    
    // 移除其他Markdown格式符号
    text = text.replace(/^\*\s/gm, ''); // 移除列表符号
    text = text.replace(/^\d+\.\s/gm, ''); // 移除有序列表
    text = text.replace(/\*\*(.+?)\*\*/g, '$1'); // 移除加粗
    text = text.replace(/\*(.+?)\*/g, '$1'); // 移除斜体
    text = text.replace(/`(.+?)`/g, '$1'); // 移除行内代码
    text = text.replace(/\[(.+?)\]\(.+?\)/g, '$1'); // 移除链接，保留文本
    text = text.replace(/!\[(.+?)\]\(.+?\)/g, '$1'); // 移除图片，保留alt文本
    
    // 清理多余的空行
    text = text.replace(/\n{3,}/g, '\n\n');
    text = text.trim();
    
    currentUtterance.value = new SpeechSynthesisUtterance(text);
    currentUtterance.value.lang = 'zh-CN';
    currentUtterance.value.rate = 1.0;
    currentUtterance.value.pitch = 1.0;
    currentUtterance.value.volume = 1.0;
    
    currentUtterance.value.onend = () => {
      isSpeaking.value = false;
      currentUtterance.value = null;
    };
    
    currentUtterance.value.onerror = (event) => {
      isSpeaking.value = false;
      currentUtterance.value = null;
      
      // 只有真正的错误才提示，取消操作不提示
      if (event.error !== 'interrupted' && event.error !== 'canceled') {
        console.error('语音播报错误:', event.error);
        // 不显示弹窗，在控制台记录即可
      }
    };
    
    window.speechSynthesis.speak(currentUtterance.value);
    isSpeaking.value = true;
  }
};

// 复制全部内容
const handleCopyAll = () => {
  // 移除HTML标签，获取纯文本
  const textarea = document.createElement('textarea');
  textarea.value = props.content;
  document.body.appendChild(textarea);
  textarea.select();
  
  try {
    document.execCommand('copy');
    isCopied.value = true;
    setTimeout(() => {
      isCopied.value = false;
    }, 2000);
  } catch (err) {
    console.error('复制失败:', err);
    alert('复制失败，请手动复制');
  } finally {
    document.body.removeChild(textarea);
  }
};

// 分享为图片
const handleShareAsImage = async () => {
  if (!messageRef.value) return;
  
  try {
    // 使用 html2canvas 将消息转换为图片
    const canvas = await html2canvas(messageRef.value, {
      backgroundColor: '#ffffff',
      scale: 2,
      logging: false,
    });
    
    // 转换为blob
    canvas.toBlob((blob) => {
      if (blob) {
        // 创建下载链接
        const url = URL.createObjectURL(blob);
        const a = document.createElement('a');
        a.href = url;
        a.download = `AI回复_${new Date().getTime()}.png`;
        document.body.appendChild(a);
        a.click();
        document.body.removeChild(a);
        URL.revokeObjectURL(url);
      }
    }, 'image/png');
  } catch (error) {
    console.error('生成图片失败:', error);
    alert('生成图片失败，请重试');
  }
};



// 重新生成处理
const handleRegenerate = () => {
  if (isRegenerating.value) return;
  emit('regenerate', props.messageId);
};

// 反馈处理（问题是否解决）
const handleFeedback = async (isResolved) => {
  if (feedbackStatus.value !== null) return; // 已经反馈过了
  
  try {
    const sessionId = localStorage.getItem('currentSession') || 'default_session';
    const api = (await import('../api')).default;
    
    await api.submitFeedback(sessionId, isResolved);
    feedbackStatus.value = isResolved;
    
    // 保存反馈状态到localStorage
    localStorage.setItem(`feedback_${messageId.value}`, JSON.stringify(isResolved));
    
    console.log(`反馈提交成功: ${isResolved ? '已解决' : '未解决'}`);
  } catch (error) {
    console.error('提交反馈失败:', error);
    alert('提交反馈失败: ' + (error.response?.data?.error || error.message));
  }
};

// 版本切换处理
const switchToPreviousVersion = () => {
  if (props.currentVersionIndex > 0) {
    emit('switch-version', props.messageId, props.currentVersionIndex - 1);
  }
};

const switchToNextVersion = () => {
  if (props.versions && props.currentVersionIndex < props.versions.length - 1) {
    emit('switch-version', props.messageId, props.currentVersionIndex + 1);
  }
};

// 组件卸载时清理语音合成
onUnmounted(() => {
  if (currentUtterance.value) {
    window.speechSynthesis.cancel();
  }
});
</script>

<style scoped>
.message {
  display: flex;
  margin-bottom: 1rem;
  max-width: 80%;
}

.message.user-message {
  margin-left: auto;
  flex-direction: row-reverse;
}

.message-avatar {
  margin-right: 0.5rem;
}

.user-message .message-avatar {
  margin-right: 0;
  margin-left: 0.5rem;
}

.user-avatar, .bot-avatar {
  width: 2.5rem;
  height: 2.5rem;
  border-radius: 50%;
  display: flex;
  justify-content: center;
  align-items: center;
  font-weight: bold;
  font-size: 0.875rem;
}

.user-avatar {
  background-color: var(--primary-color);
  color: white;
}

.bot-avatar {
  background-color: var(--secondary-color);
  color: white;
}

.message-content {
  padding: 0.75rem 1rem;
  border-radius: var(--radius);
  position: relative;
}

.message:not(.user-message) .message-content {
  background-color: var(--bot-message);
}

.user-message .message-content {
  background-color: var(--user-message);
}

.message-text {
  margin-bottom: 0.25rem;
  line-height: 1.5;
}

.message-footer {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  margin-top: 0.75rem;
  padding-top: 0.5rem;
}

.message-footer-meta {
  display: flex;
  justify-content: space-between;
  align-items: center;
  width: 100%;
}

.message-time {
  font-size: 0.75rem;
  color: var(--text-secondary);
}

.unknown-time {
  font-style: italic;
  color: #999;
  opacity: 0.7;
}

.user-message .message-time {
  text-align: right;
}

/* Markdown样式 */
.message-text :deep(h1) {
  font-size: 1.5rem;
  font-weight: bold;
  margin: 0.75rem 0 0.5rem 0;
  color: #1a202c;
}

.message-text :deep(h2) {
  font-size: 1.25rem;
  font-weight: bold;
  margin: 0.75rem 0 0.5rem 0;
  color: #2d3748;
}

.message-text :deep(h3) {
  font-size: 1.1rem;
  font-weight: bold;
  margin: 0.5rem 0 0.375rem 0;
  color: #4a5568;
}

.message-text :deep(ul) {
  margin: 0.5rem 0;
  padding-left: 1.5rem;
  list-style-type: disc;
}

.message-text :deep(ol) {
  margin: 0.5rem 0;
  padding-left: 1.5rem;
  list-style-type: decimal;
}

.message-text :deep(li) {
  margin: 0.25rem 0;
  line-height: 1.6;
}

.message-text :deep(a) {
  color: #3b82f6;
  text-decoration: underline;
  transition: color 0.2s;
}

.message-text :deep(a:hover) {
  color: #2563eb;
}

.message-text :deep(strong) {
  font-weight: bold;
  color: #1a202c;
}

.message-text :deep(em) {
  font-style: italic;
  color: #4a5568;
}

.message-text :deep(code) {
  padding: 0.125rem 0.375rem;
  background-color: #f1f5f9;
  border-radius: 0.25rem;
  font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', 'Courier New', monospace;
  font-size: 0.875rem;
  color: #c7254e;
  border: 1px solid #ffe5ec;
}

.message-text :deep(pre) {
  margin: 0.75rem 0;
  padding: 0;
  background-color: #f8f8f8;
  border-radius: 0.5rem;
  overflow-x: auto;
  border: 1px solid #e5e7eb;
}

.message-text :deep(pre code) {
  display: block;
  padding: 1rem;
  background-color: transparent;
  border-radius: 0;
  font-size: 0.875rem;
  line-height: 1.6;
  color: inherit;
  font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', 'Courier New', monospace;
  border: none;
}

.message-text :deep(pre code.hljs) {
  background: #f8f8f8;
}

/* 复制按钮样式 */
.message-text :deep(pre .copy-btn) {
  position: absolute;
  top: 0.5rem;
  right: 0.5rem;
  padding: 0.25rem 0.75rem;
  background: rgba(255, 255, 255, 0.9);
  border: 1px solid #d1d5db;
  border-radius: 0.375rem;
  font-size: 0.75rem;
  cursor: pointer;
  transition: all 0.2s;
  color: #6b7280;
  font-weight: 500;
  z-index: 10;
}

.message-text :deep(pre .copy-btn:hover) {
  background: #f3f4f6;
  border-color: #9ca3af;
  color: #374151;
}

.message-text :deep(pre .copy-btn.copied) {
  background: #dcfce7;
  border-color: #86efac;
  color: #16a34a;
}

/* 折叠按钮样式 */
.collapse-btn {
  display: block;
  margin: 0.5rem auto 0 auto;
  padding: 0.375rem 1rem;
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  color: white;
  border: none;
  border-radius: 1rem;
  font-size: 0.875rem;
  cursor: pointer;
  transition: all 0.3s;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}

.collapse-btn:hover {
  transform: translateY(-1px);
  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15);
  background: linear-gradient(135deg, #764ba2 0%, #667eea 100%);
}

.collapse-btn:active {
  transform: translateY(0);
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}

/* 折叠状态 */
.message-text.collapsed {
  max-height: 500px;
  overflow: hidden;
  position: relative;
}

.message-text.collapsed::after {
  content: '';
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  height: 100px;
  background: linear-gradient(to bottom, transparent, var(--bot-message));
  pointer-events: none;
}

/* LaTeX公式样式 */
.message-text :deep(.katex) {
  font-size: 1.1em;
  color: #2d3748;
}

.message-text :deep(.katex-display) {
  margin: 1rem 0;
  overflow-x: auto;
  overflow-y: hidden;
}

.message-text :deep(.latex-block) {
  text-align: center;
  margin: 1rem 0;
  padding: 1rem;
  background: #f8fafc;
  border-radius: 0.5rem;
  border: 1px solid #e5e7eb;
}

/* 操作栏样式 */
.message-actions {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  opacity: 0;
  transition: opacity 0.2s ease;
}

.message:hover .message-actions {
  opacity: 1;
}

/* 反馈按钮组 */
.feedback-buttons {
  display: flex;
  gap: 0.5rem;
  margin-right: 0.5rem;
  padding-right: 0.5rem;
  border-right: 1px solid rgba(255, 255, 255, 0.1);
}

.feedback-btn {
  display: flex;
  align-items: center;
  gap: 0.25rem;
  padding: 0.375rem 0.75rem;
  background: rgba(255, 255, 255, 0.05);
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 6px;
  cursor: pointer;
  transition: all 0.2s ease;
  font-size: 0.813rem;
  color: rgba(255, 255, 255, 0.7);
}

.feedback-btn:hover:not(:disabled) {
  background: rgba(255, 255, 255, 0.1);
  border-color: rgba(255, 255, 255, 0.2);
  transform: translateY(-1px);
}

.feedback-btn:disabled {
  cursor: not-allowed;
  opacity: 0.6;
}

.feedback-btn.active {
  background: linear-gradient(135deg, #3b82f6, #2563eb);
  border-color: #3b82f6;
  color: #fff;
  box-shadow: 0 2px 8px rgba(59, 130, 246, 0.3);
}

.feedback-icon {
  font-size: 1.125rem;
  line-height: 1;
}

.action-btn {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  padding: 0;
  background: transparent;
  border: none;
  border-radius: 6px;
  cursor: pointer;
  transition: all 0.2s ease;
  color: #8b8e96;
}

.action-btn:hover {
  background: rgba(0, 0, 0, 0.05);
  color: #373a40;
}

.action-btn.active {
  background: #e3f2fd;
  color: #1976d2;
}

.action-btn.copied {
  background: #e8f5e9;
  color: #388e3c;
}

.action-btn svg {
  flex-shrink: 0;
  pointer-events: none;
}

.action-btn.reload-btn:hover {
  background: #e8f5e9;
  color: #2e7d32;
}

/* 版本导航样式 */
.version-nav {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0;
  background: transparent;
  font-size: 0.875rem;
  margin-top: 0.5rem;
  justify-content: center;
}

.version-nav-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  padding: 0;
  background: transparent;
  border: none;
  border-radius: 4px;
  cursor: pointer;
  transition: all 0.2s ease;
  color: #8b8e96;
}

.version-nav-btn:hover:not(:disabled) {
  background: rgba(0, 0, 0, 0.08);
  color: #373a40;
}

.version-nav-btn:disabled {
  opacity: 0.3;
  cursor: not-allowed;
}

.version-count {
  color: #6b7280;
  font-weight: 500;
  font-size: 0.75rem;
  min-width: 2.5rem;
  text-align: center;
}

.action-text {
  position: absolute;
  bottom: 100%;
  left: 50%;
  transform: translateX(-50%);
  margin-bottom: 8px;
  padding: 4px 8px;
  background: rgba(0, 0, 0, 0.75);
  color: white;
  font-size: 12px;
  white-space: nowrap;
  border-radius: 4px;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.2s ease;
}

.action-btn:hover .action-text {
  opacity: 1;
}

.action-text::after {
  content: '';
  position: absolute;
  top: 100%;
  left: 50%;
  transform: translateX(-50%);
  border: 4px solid transparent;
  border-top-color: rgba(0, 0, 0, 0.75);
}

/* 响应式优化 */
@media (max-width: 768px) {
  .message-text :deep(pre .copy-btn) {
    font-size: 0.7rem;
    padding: 0.2rem 0.5rem;
  }
  
  .collapse-btn {
    font-size: 0.8rem;
    padding: 0.3rem 0.8rem;
  }
  
  .action-btn {
    width: 32px;
    height: 32px;
  }
  
  .action-btn svg {
    width: 20px;
    height: 20px;
  }
}
</style>
